package com.zlyx.easy.log.aspect;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

import javax.validation.constraints.NotNull;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.lang.NonNull;

import com.zlyx.easy.core.annotations.SpringBean;
import com.zlyx.easy.core.tool.Ops;
import com.zlyx.easy.core.utils.LogUtils;
import com.zlyx.easy.core.utils.MethodUtils;
import com.zlyx.easy.core.utils.ObjectUtils;
import com.zlyx.easy.core.utils.ProxyUtils;
import com.zlyx.easy.log.annotations.EasyLog;
import com.zlyx.easy.log.aspect.abstracts.AbstractLogAspect;

@Aspect
@SpringBean(todo = "日志切面")
public class LogAspect extends AbstractLogAspect {

	@Pointcut("@annotation(com.zlyx.easy.log.annotations.EasyLog)")
	public void logAspect() {
	}

	@Around("logAspect()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		Object res = null;
		Signature signature = pjp.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method targetMethod = methodSignature.getMethod();
		Class<?> realClass = ProxyUtils.getTarget(pjp.getTarget()).getClass();
		Method realMethod = MethodUtils.getRealMethod(realClass, targetMethod);
		EasyLog easyLog = realMethod.getAnnotation(EasyLog.class);
		if (doValidate(pjp.getArgs(), realMethod)) {
			if (properties.getLevel() <= 1) {
				res = doPrint(pjp, realClass, realMethod,
						Ops.isEmpty(easyLog.value()) ? realMethod.getName() : easyLog.value(), easyLog.todo());
			} else {
				res = doProcess(pjp, realClass, realMethod);
			}
		} else {
			LogUtils.err(realClass, realMethod.getName() + "@参数校验不通过!");
		}
		return res;
	}

	/**
	 * 校验参数是否为空
	 * 
	 * @param pjp
	 * @param method
	 * @param easyJob
	 * @return
	 */
	private boolean doValidate(Object[] args, Method method) {
		Parameter[] paramters = method.getParameters();
		if (paramters != null && paramters.length > 0) {
			for (int i = 0; i < paramters.length; i++) {
				if ((paramters[i].getAnnotation(NonNull.class) != null
						|| paramters[i].getAnnotation(NotNull.class) != null) && ObjectUtils.isEmpty(args[i])) {
					return false;
				}
			}
		}
		return true;
	}
}
